// 引入axios
import axios from "axios";
import { ElMessage } from "element-plus";
import store from "@/store";
import router from "../router";
import { getToken } from "@/utils/common";

/**
 * @description: 校验网络请求状态码
 * @param {Number} status
 * @return void
 */
export const checkStatus = (status) => {
  switch (status) {
    case 400:
      ElMessage.error("请求失败！请您稍后重试");
      break;
    case 401:
      ElMessage.error("登录失效！请您重新登录");
      store.dispatch("user/logout");
      router.replace({ name: "login" })
      break;
    case 403:
      ElMessage.error("当前账号无权限访问！");
      break;
    case 404:
      ElMessage.error("你所访问的资源不存在！");
      break;
    case 405:
      ElMessage.error("请求方式错误！请您稍后重试");
      break;
    case 408:
      ElMessage.error("请求超时！请您稍后重试");
      break;
    case 500:
      ElMessage.error("服务异常！");
      break;
    case 502:
      ElMessage.error("网关错误！");
      break;
    case 503:
      ElMessage.error("服务不可用！");
      break;
    case 504:
      ElMessage.error("网关超时！");
      break;
    default:
      ElMessage.error("请求失败！");
  }
};

// 设置一些默认的请求配置
const defaultconfig = {
  baseURL: "/api",
  timeout: 10 * 1000,
};

class Request {
  constructor(config) {
    this.instance = axios.create(config);
    // 请求拦截器
    this.instance.interceptors.request.use(
      (config) => {
        // 1、获取token
        const token = getToken();
        // 2、判断是否有token
        if (token) {
          // 3、设置请求头
          config.headers.Authorization = token;
        }
        return config;
      },
      (error) => {
        const response = error.response;
        // 请求超时 && 网络错误单独判断，没有 response
        if (error.message.indexOf("timeout") !== -1)
          ElMessage.error("请求超时！请您稍后重试");
        if (error.message.indexOf("Network Error") !== -1)
          ElMessage.error("网络错误！请您稍后重试");
        if (response) checkStatus(response.status);

        return Promise.reject(error);
      }
    );
    // 响应拦截器
    this.instance.interceptors.response.use(
      /**
       * 2xx 范围内的状态码都会触发该函数。
       * 对响应数据做点什么
       * @param {*} response Axios封装对象
       * @returns 必须要返回，如果没有返回的话，业务上的 .then 就触发不了，这里 返回的内容是给到 .then 回调函数的参数的
       */
      (response) => {
        // 1. 获取 result [接口返回值]
        const result = response.data;

        // 2. 判断业务状态码
        if (result.code !== 1000) {
          // alert(result.message);
          ElMessage.error(result.message);
          // ElMessage({
          //   type: "error",
          //   message: result.message,
          // });
          return Promise.reject(result);
        }

        return result.data;
      }
    );
  }

  get(url, params = {}, config = {}) {
    return this.instance.get(url, {
      ...config,
      params,
    });
  }
  post(url, params = {}, config = {}) {
    return this.instance.post(url, params, {
      ...config,
    });
  }
}

// 导出实例
export default new Request(defaultconfig);
